package indi.lddsdu.spider;

/*
 *包引入的顺序  java javax 第三方类包 自己定义的类
 */

import java.util.List;
import com.beust.jcommander.JCommander;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.Pipeline;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.Scheduler;
import indi.lddsdu.spider.args.CommandArgs;
import indi.lddsdu.spider.bean.RuntimeParameter;
import indi.lddsdu.spider.bean.UnDownloadUrl;
import indi.lddsdu.spider.conponent.ViewPipeline;
import indi.lddsdu.spider.conponent.ViewProcessor;
import indi.lddsdu.spider.conponent.ViewScheduler;
import indi.lddsdu.spider.utils.ProcessUtil;


/**
 * Created by jack on 18/6/4.
 * 爬虫的主入口
 */
public class Main {

    static Logger logger = LoggerFactory.getLogger(Main.class);
    static ProcessUtil processUtil;
    private static ApplicationContext context =
            new ClassPathXmlApplicationContext("view.xml"); //使用view.xml来进行对于对象的组装,创建这个对象的时候便去自动扫描了

    static{
        processUtil = context.getBean(ProcessUtil.class);
        try {
            Class.forName("indi.lddsdu.spider.bean.RuntimeParameter");
        } catch (ClassNotFoundException e) {
            //TODO 这里出错了则直接退出，打印错误没有作用
            System.out.println(e);
        }
    }

    /**
     * 处理中断，在发生中断时执行，或者是在程序截止时执行
     */
    public static class CtrlCHandler extends Thread{
        private Scheduler scheduler;
        private Spider spider;
        public CtrlCHandler(Scheduler scheduler, Spider spider) {
            this.scheduler = scheduler;
            this.spider = spider;
        }
        @Override
        public void run() {
            super.run();
            //TODO 将其中的scheduler中的数据存储进数据库中,目前只是将其打印了出来
            Request request = null;
            int index = 0;
            while ((request = scheduler.poll(spider)) != null){

                //在机器shutdown的时候将数据全部存储进UnDownloadUrl中
                processUtil.storeUnDownloadUrl(new UnDownloadUrl(request.getUrl()));
//              System.out.println(String.format("index %06d url: %s", index++, request.getUrl()));
            }
        }
    }

    public static void main(String[] args) {

        try {
            CommandArgs ca = new CommandArgs();
            new JCommander(ca, args);
            String htmlFolder = ca.getHtmlFolder();
            String imgFolder = ca.getImgFolder();
            if(htmlFolder == null || imgFolder == null){
                throw new Exception("没有对应的命令行参数,是否选择默认的参数");
            }
            RuntimeParameter.setPersistenceHtmlFolder(htmlFolder);
            RuntimeParameter.setPersistenceImageFolder(imgFolder);
        }catch (Exception e){
            logger.info("may use the default folder path");
            logger.warn("e : " + e);
        }

        PageProcessor pageProcessor= context.getBean(ViewProcessor.class);

        Pipeline pipeline = context.getBean(ViewPipeline.class);

        ViewScheduler scheduler = context.getBean(ViewScheduler.class);

        List<Request> requestList = processUtil.findAllUnDownloadUrlAndThenDeleteAll();

        Spider spider = null;

        spider = Spider.create(pageProcessor).addPipeline(pipeline)
                    .setScheduler(scheduler).thread(30);

        //在没有初始的启动url时，添加首页的url
        if (requestList.size() == 0){

            spider.addUrl("http://www.view.sdu.edu.cn/");

        }

        for( Request request : requestList){
            scheduler.push(request, spider);
        }

        Runtime.getRuntime().addShutdownHook(new CtrlCHandler(scheduler, spider));

        spider.run();

        System.err.println("run");
    }


}
